use moka::sync::Cache;
use once_cell::sync::OnceCell;
use std::time::Duration;

use super::util_date;

static CACHE_STR: OnceCell<Cache<String, String>> = OnceCell::new();
static CACHE_I64: OnceCell<Cache<String, i64>> = OnceCell::new();

pub fn init_cache() {
    let ttl_time = Duration::from_secs(14400); // 14400秒， 4个小时
    let cache_str: Cache<String, String> = Cache::builder().time_to_idle(ttl_time).build(); // 记录字符串值
    let cache_i64: Cache<String, i64> = Cache::builder().time_to_idle(ttl_time).build(); // 记录对应值的有效时间，时间戳（毫秒）
    let _ = CACHE_STR.set(cache_str);
    let _ = CACHE_I64.set(cache_i64);
}

/// 设置值，
/// 参数： k：键， v：值， sec：有效期（秒）如果为0则表示无时间限制
pub fn set(k: &str, v: String, sec: i64) -> bool {
    if let Some(cs) = CACHE_STR.get() {
        if let Some(ci) = CACHE_I64.get() {
            cs.insert(k.to_string(), v); // 设置值

            // 如果 有效期 == 0 则无限
            let step_mill = if sec == 0 {
                30 * 86400 * 1000 // 30天
            } else {
                sec * 1000
            };

            //let now = util_date::now_milliseconds();
            //log::info!("\n\n\n\n now:{} step_mill:{}\n\n\n\n", now, step_mill);

            let mill = util_date::now_milliseconds() + step_mill;
            ci.insert(k.to_string(), mill); // 设置该值的有效期。（k 相同）
            true
        } else {
            false
        }
    } else {
        false
    }
}

/// 读取值
///
pub fn get(k: &str) -> Option<String> {
    if let Some(cs) = CACHE_STR.get() {
        if let Some(ci) = CACHE_I64.get() {
            if let Some(v) = cs.get(k) {
                if let Some(t) = ci.get(k) {
                    let now = util_date::now_milliseconds();
                    //log::info!("\n\n\n\n k:{} v:{} t:{} now:{}\n\n\n\n", k, v, t, now);
                    if t > now {
                        Some(v)
                    } else {
                        cs.remove(k);
                        ci.remove(k);
                        None
                    }
                } else {
                    None
                }
            } else {
                None
            }
        } else {
            None
        }
    } else {
        None
    }
}

/// 是否包含值
#[allow(dead_code)]
pub fn contain(k: &str) -> bool {
    if let Some(cs) = CACHE_STR.get() {
        if let Some(ci) = CACHE_I64.get() {
            if let Some(_) = cs.get(k) {
                if let Some(t) = ci.get(k) {
                    let now = util_date::now_milliseconds();
                    if t > now {
                        true
                    } else {
                        cs.remove(k);
                        ci.remove(k);
                        false
                    }
                } else {
                    false
                }
            } else {
                false
            }
        } else {
            false
        }
    } else {
        false
    }
}

/// 删除值
#[allow(dead_code)]
pub fn delete(k: &str) -> bool {
    if let Some(cs) = CACHE_STR.get() {
        if let Some(ci) = CACHE_I64.get() {
            cs.remove(k);
            ci.remove(k);
            true
        } else {
            false
        }
    } else {
        false
    }
}
